package com.netdisk.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.netdisk.dto.FileDTO;
import com.netdisk.dto.ShareDTO;
import com.netdisk.entity.Share;
import com.netdisk.exception.BusinessException;
import com.netdisk.mapper.ShareMapper;
import com.netdisk.service.FileService;
import com.netdisk.service.ShareService;
import com.netdisk.vo.PageResult;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;

/**
 * 分享服务实现类
 */
@Service
public class ShareServiceImpl extends ServiceImpl<ShareMapper, Share> implements ShareService {

    @Autowired
    private FileService fileService;

    @Override
    public ShareDTO createShare(Integer fileId, Integer userId) {
        try {
            // 检查文件是否存在
            FileDTO fileDTO = fileService.getFileInfo(fileId, userId);
            if (fileDTO == null) {
                throw new BusinessException("文件不存在");
            }

            // 使用自定义mapper方法检查是否已经分享过，绕过MyBatis-Plus的逻辑删除功能
            Share existingShare = baseMapper.findExistingShare(fileId, userId);
            
            if (existingShare != null) {
                // 已存在分享，返回已有分享
                ShareDTO shareDTO = new ShareDTO();
                BeanUtils.copyProperties(existingShare, shareDTO);
                shareDTO.setFile(fileDTO);
                return shareDTO;
            }

            // 创建新分享
            Share share = new Share();
            share.setFileId(fileId);
            share.setUserId(userId);
            share.setShareId(generateShareId());
            share.setCreatedAt(LocalDateTime.now());
            share.setExpiresAt(LocalDateTime.now().plusDays(7)); // 默认7天过期
            
            // 保存分享
            this.save(share);
            
            // 返回分享信息
            ShareDTO shareDTO = new ShareDTO();
            BeanUtils.copyProperties(share, shareDTO);
            shareDTO.setFile(fileDTO);
            
            return shareDTO;
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("创建分享失败：" + e.getMessage());
        }
    }
    
    @Override
    public ShareDTO getShareInfo(String shareId) {
        // 使用自定义mapper方法查询分享信息，绕过MyBatis-Plus的逻辑删除功能
        Share share = baseMapper.findByShareId(shareId);
        
        if (share == null) {
            throw new BusinessException("分享不存在或已失效");
        }
        
        // 检查是否过期
        if (share.getExpiresAt() != null && share.getExpiresAt().isBefore(LocalDateTime.now())) {
            throw new BusinessException("分享已过期");
        }
        
        // 获取文件信息
        FileDTO fileDTO = fileService.getFileInfo(share.getFileId(), share.getUserId());
        if (fileDTO == null) {
            throw new BusinessException("分享的文件不存在");
        }
        
        // 构建并返回分享DTO
        ShareDTO shareDTO = new ShareDTO();
        BeanUtils.copyProperties(share, shareDTO);
        shareDTO.setFile(fileDTO);
        
        return shareDTO;
    }

    @Override
    public boolean cancelShare(String shareId, Integer userId) {
        try {
            System.out.println("取消分享: shareId=" + shareId + ", userId=" + userId);
            
            // 使用自定义mapper方法查询分享信息，绕过MyBatis-Plus的逻辑删除功能
            Share share = baseMapper.findByShareIdAndUserId(shareId, userId);
            
            if (share == null) {
                System.out.println("找不到分享记录: shareId=" + shareId + ", userId=" + userId);
                
                // 尝试使用只有shareId的查询
                Share shareByIdOnly = baseMapper.findByShareId(shareId);
                if (shareByIdOnly != null) {
                    System.out.println("只通过shareId找到分享，但用户ID不匹配: foundUserId=" + shareByIdOnly.getUserId() + ", requestUserId=" + userId);
                    throw new BusinessException("无权取消该分享");
                }
                
                throw new BusinessException("分享不存在或已失效");
            }
            
            System.out.println("找到分享记录: " + share.getId() + ", 文件ID=" + share.getFileId());
            
            // 使用自定义mapper方法进行逻辑删除，避免MyBatis-Plus的逻辑删除冲突
            int result = baseMapper.markAsDeleted(share.getId());
            System.out.println("更新结果: " + result);
            
            return result > 0;
        } catch (Exception e) {
            System.err.println("取消分享发生异常: " + e.getMessage());
            e.printStackTrace();
            throw e; // 重新抛出异常，以便上层捕获
        }
    }

    @Override
    public PageResult<ShareDTO> listUserShares(Integer userId, Integer page, Integer pageSize) {
        // 调用带查询参数的方法，传入空字符串作为查询条件
        return listUserShares(userId, page, pageSize, "");
    }
    
    @Override
    public PageResult<ShareDTO> listUserShares(Integer userId, Integer page, Integer pageSize, String query) {
        try {
            // 计算偏移量
            Integer offset = (page - 1) * pageSize;
            
            List<Share> shares;
            Long total;
            
            // 根据是否有查询参数决定使用哪个查询方法
            if (query == null || query.trim().isEmpty()) {
                // 无查询参数，使用普通查询
                shares = baseMapper.findSharesByUserId(userId, offset, pageSize);
                total = baseMapper.countSharesByUserId(userId);
            } else {
                // 有查询参数，使用带查询条件的方法
                shares = baseMapper.findSharesByUserIdWithQuery(userId, query, offset, pageSize);
                total = baseMapper.countSharesByUserIdWithQuery(userId, query);
            }
            
            // 转换为DTO，同时过滤掉文件已删除的分享
            List<ShareDTO> shareDTOList = new ArrayList<>();
            
            for (Share share : shares) {
                try {
                    // 检查分享是否过期
                    if (share.getExpiresAt() != null && share.getExpiresAt().isBefore(LocalDateTime.now())) {
                        // 分享已过期，自动取消分享
                        System.out.println("分享ID=" + share.getShareId() + "已过期，自动取消分享");
                        baseMapper.markAsDeleted(share.getId());
                        if (total > 0) {
                            total--;
                        }
                        continue;
                    }
                    // 尝试获取文件信息
                    FileDTO fileDTO = fileService.getFileInfo(share.getFileId(), userId);
                    // 如果文件存在，则添加到结果列表
                    if (fileDTO != null) {
                        ShareDTO shareDTO = new ShareDTO();
                        BeanUtils.copyProperties(share, shareDTO);
                        shareDTO.setFile(fileDTO);
                        shareDTOList.add(shareDTO);
                    } else {
                        // 文件不存在，标记该分享为已删除
                        System.out.println("分享ID=" + share.getShareId() + "对应的文件ID=" + share.getFileId() + "已被删除，自动取消分享");
                        baseMapper.markAsDeleted(share.getId());
                        if (total > 0) {
                            total--;
                        }
                    }
                } catch (Exception e) {
                    // 获取文件信息出错，记录日志但不中断处理
                    System.err.println("获取分享文件信息出错: " + e.getMessage());
                }
            }
            
            // 返回分页结果
            return new PageResult<>(total, shareDTOList);
        } catch (Exception e) {
            // 记录异常并返回空结果
            e.printStackTrace();
            return new PageResult<>(0L, Collections.emptyList());
        }
    }
    
    @Override
    public FileDTO getShareFileInfo(String shareId) {
        // 使用自定义mapper方法查询分享信息，绕过MyBatis-Plus的逻辑删除功能
        Share share = baseMapper.findByShareId(shareId);
        
        if (share == null) {
            throw new BusinessException("分享不存在或已失效");
        }
        
        // 检查是否过期
        if (share.getExpiresAt() != null && share.getExpiresAt().isBefore(LocalDateTime.now())) {
            throw new BusinessException("分享已过期");
        }
        
        // 获取文件信息
        FileDTO fileDTO = fileService.getFileInfo(share.getFileId(), share.getUserId());
        if (fileDTO == null) {
            throw new BusinessException("分享的文件不存在");
        }
        
        return fileDTO;
    }
    
    /**
     * 生成唯一分享ID
     * 
     * @return 分享ID
     */
    private String generateShareId() {
        return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 12);
    }
}